// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.iso;

import java.util.ArrayList;
import java.util.concurrent.ConcurrentLinkedQueue;
import zombie.core.Core;
import zombie.core.ThreadGroups;
import zombie.debug.DebugLog;
import zombie.iso.objects.IsoTree;
import zombie.network.MPStatistic;

public final class WorldReuserThread {
    public static final WorldReuserThread instance = new WorldReuserThread();
    private final ArrayList<IsoObject> objectsToReuse = new ArrayList();
    private final ArrayList<IsoTree> treesToReuse = new ArrayList();
    public boolean finished;
    private Thread worldReuser;
    private final ConcurrentLinkedQueue<IsoChunk> reuseGridSquares = new ConcurrentLinkedQueue();

    public void run() {
        this.worldReuser = new Thread(ThreadGroups.Workers, () -> {
            while (!this.finished) {
                MPStatistic.getInstance().WorldReuser.Start();
                this.testReuseChunk();
                this.reconcileReuseObjects();
                MPStatistic.getInstance().WorldReuser.End();

                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException interruptedException) {
                    interruptedException.printStackTrace();
                }
            }
        });
        this.worldReuser.setName("WorldReuser");
        this.worldReuser.setDaemon(true);
        this.worldReuser.setUncaughtExceptionHandler(zombie.GameWindow::uncaughtException);
        this.worldReuser.start();
    }

    public void reconcileReuseObjects() {
        synchronized (this.objectsToReuse) {
            if (!this.objectsToReuse.isEmpty()) {
                synchronized (CellLoader.isoObjectCache) {
                    if (CellLoader.isoObjectCache.size() < 320000) {
                        CellLoader.isoObjectCache.addAll(this.objectsToReuse);
                    }
                }

                this.objectsToReuse.clear();
            }
        }

        synchronized (this.treesToReuse) {
            if (!this.treesToReuse.isEmpty()) {
                synchronized (CellLoader.isoTreeCache) {
                    if (CellLoader.isoTreeCache.size() < 40000) {
                        CellLoader.isoTreeCache.addAll(this.treesToReuse);
                    }
                }

                this.treesToReuse.clear();
            }
        }
    }

    public void testReuseChunk() {
        for (IsoChunk isoChunk = (IsoChunk)this.reuseGridSquares.poll(); isoChunk != null; isoChunk = (IsoChunk)this.reuseGridSquares.poll()) {
            if (Core.bDebug) {
                if (ChunkSaveWorker.instance.toSaveQueue.contains(isoChunk)) {
                    DebugLog.log("ERROR: reusing chunk that needs to be saved");
                }

                if (IsoChunkMap.chunkStore.contains(isoChunk)) {
                    DebugLog.log("ERROR: reusing chunk in chunkStore");
                }

                if (!isoChunk.refs.isEmpty()) {
                    DebugLog.log("ERROR: reusing chunk with refs");
                }
            }

            if (Core.bDebug) {
            }

            this.reuseGridSquares(isoChunk);
            if (this.treesToReuse.size() > 1000 || this.objectsToReuse.size() > 5000) {
                this.reconcileReuseObjects();
            }
        }
    }

    public void addReuseChunk(IsoChunk chunk) {
        this.reuseGridSquares.add(chunk);
    }

    public void reuseGridSquares(IsoChunk chunk) {
        byte _byte = 100;

        for (int int0 = 0; int0 < 8; int0++) {
            for (int int1 = 0; int1 < _byte; int1++) {
                IsoGridSquare isoGridSquare = chunk.squares[int0][int1];
                if (isoGridSquare != null) {
                    for (int int2 = 0; int2 < isoGridSquare.getObjects().size(); int2++) {
                        IsoObject isoObject = isoGridSquare.getObjects().get(int2);
                        if (isoObject instanceof IsoTree) {
                            isoObject.reset();
                            synchronized (this.treesToReuse) {
                                this.treesToReuse.add((IsoTree)isoObject);
                            }
                        } else if (isoObject.getClass() == IsoObject.class) {
                            isoObject.reset();
                            synchronized (this.objectsToReuse) {
                                this.objectsToReuse.add(isoObject);
                            }
                        } else {
                            isoObject.reuseGridSquare();
                        }
                    }

                    isoGridSquare.discard();
                    chunk.squares[int0][int1] = null;
                }
            }
        }

        chunk.resetForStore();
        IsoChunkMap.chunkStore.add(chunk);
    }
}
